#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
+#include <sys/ioctl.h>
#include "hypervisor_defs.h"
#include "dom0_ops.h"
/* clean up domain's memory allocations */
static void dom_mem_cleanup(dom_mem_t * dom_mem)
{
- char mem_path[MAX_PATH];
- int mem_fd;
-
- /* open the domain's /proc mem interface */
- sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/",
- PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM);
+ int fd;
+ struct dom0_unmapdommem_args argbuf;
- mem_fd = open(mem_path, O_WRONLY);
- if(mem_fd < 0){
+ fd = open("/proc/xeno/dom0_cmd", O_WRONLY);
+ if(fd < 0){
perror(PERR_STRING);
}
- if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){
- dbstatus("Error unmapping domain's memory.\n");
+ argbuf.vaddr = dom_mem->vaddr;
+ argbuf.start_pfn = dom_mem->start_pfn;
+ argbuf.tot_pages = dom_mem->tot_pages;
+
+ if (ioctl(fd, IOCTL_DOM0_UNMAPDOMMEM, &argbuf) < 0) {
+ dbstatus("Error unmapping domain's memory.\n");
}
- close(mem_fd);
+ close(fd);
}
/* ask dom0 to export domains memory through /proc */
static int map_dom_mem(unsigned long pfn, int pages, int dom,
dom_mem_t * dom_mem)
{
-
- if(setup_dom_memmap(pfn, pages, dom)){
- perror(PERR_STRING);
- return -1;
- }
-
- dom_mem->domain = dom;
- dom_mem->start_pfn = pfn;
- dom_mem->tot_pages = pages;
- if((dom_mem->vaddr = get_vaddr(dom)) == 0){
- dberr("Error mapping dom memory.");
- return -1;
- }
-
- return 0;
+ struct dom0_mapdommem_args argbuf;
+ int fd;
+
+ argbuf.domain = dom;
+ argbuf.start_pfn = pfn;
+ argbuf.tot_pages = pages;
+
+ fd = open("/proc/xeno/dom0_cmd", O_RDWR);
+ if (fd < 0) {
+ perror("openning /proc/xeno/dom0_cmd");
+ return -1;
+ }
+
+ dom_mem->domain = dom;
+ dom_mem->start_pfn = pfn;
+ dom_mem->tot_pages = pages;
+ dom_mem->vaddr = ioctl(fd, IOCTL_DOM0_MAPDOMMEM, &argbuf);
+
+ if (dom_mem->vaddr == -1) {
+ perror("mapping domain memory");
+ return -1;
+ }
+
+ return 0;
}
/* open kernel image and do some sanity checks */
pgt_updates = (page_update_request_t *)dom_mem->vaddr;
alloc_index = dom_mem->tot_pages - 1;
- memset(meminfo, 0, sizeof(meminfo));
+ memset(meminfo, 0, sizeof(*meminfo));
memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
#define MAX_CMD_LEN 256
#define MAX_DOMAIN_NAME 16
-#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_NONE, 'x', 0, 0)
-
typedef struct dom0_newdomain_st
{
unsigned int domain; // return parameter
} dom0_op_t;
#endif
-/* Arguments to the CREATEDOMAIN ioctl on /proc/xeno/dom0_cmd.
- Probably belongs in a Linux include file somewhere... */
+/* These really belong in a Linux header file somewhere.
+ XXX.
+*/
+#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_READ, 'x', 0, sizeof(struct dom0_createdomain_args))
+#define IOCTL_DOM0_MAPDOMMEM _IOC(_IOC_READ, 'x', 1, sizeof(struct dom0_mapdommem_args))
+#define IOCTL_DOM0_UNMAPDOMMEM _IOC(_IOC_READ, 'x', 2, sizeof(struct dom0_unmapdommem_args))
+
struct dom0_createdomain_args
{
unsigned int kb_mem;
const char *name;
};
+struct dom0_mapdommem_args
+{
+ unsigned int domain;
+ unsigned start_pfn;
+ unsigned tot_pages;
+};
+
+struct dom0_unmapdommem_args
+{
+ unsigned long vaddr;
+ unsigned long start_pfn;
+ unsigned long tot_pages;
+};
+
#endif
{
dom_mem_t mem_data;
+ printk("dom_mem_write called: Shouldn't happen.\n");
+
copy_from_user(&mem_data, (dom_mem_t *)buff, sizeof(dom_mem_t));
if(direct_disc_unmap(mem_data.vaddr, mem_data.start_pfn,
/* remap the range using xen specific routines */
+ printk("Calling direct_mmap with pfn %x, tot pages %x.\n",
+ mem_data->pfn, mem_data->tot_pages);
+
addr = direct_mmap(mem_data->pfn << PAGE_SHIFT, mem_data->tot_pages << PAGE_SHIFT, prot, MAP_DISCONT, mem_data->tot_pages);
copy_to_user((unsigned long *)buff, &addr, sizeof(addr));
/* check if there is already an entry for mem and if so
* remove it.
*/
+ /* XXX does this not leak the memdata? */
remove_proc_entry("mem", pd);
/* create new entry with parameters describing what to do
{
ret = dom_map_mem(op.u.dommem.domain, op.u.dommem.start_pfn,
op.u.dommem.tot_pages);
+ /* This is now an ioctl, and shouldn't be being written to
+ the command file. */
+ // printk("map_dom_mem dom0_cmd used!\n");
+ // ret = -EOPNOTSUPP;
}
else if ( op.cmd == DO_PGUPDATES )
{
dom0_op_t op;
int ret;
- if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf))) {
- printk("fault getting argbuf.\n");
+ if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
return -EFAULT;
- }
op.cmd = DOM0_CREATEDOMAIN;
op.u.newdomain.domain = -666;
op.u.newdomain.memory_kb = argbuf.kb_mem;
op.u.newdomain.num_vifs = 0; /* Not used anymore, I hope... */
namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
- if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1)) {
- printk("Fault getting domain name\n");
+ if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1))
return -EFAULT;
- }
/* Error checking? The old code deosn't appear to do any, and I
can't see where the return values are documented... */
return ret;
}
+static unsigned long handle_dom0_cmd_mapdommem(unsigned long data)
+{
+ struct dom0_mapdommem_args argbuf;
+ unsigned long addr;
+
+ if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
+ return -EFAULT;
+ /* This seems to be assuming that the root of the page table is in
+ the first frame of the new domain's physical memory? */
+ /* XXX do I really mean this? */
+ /* XXX what happens if userspace forgets to do the unmap? */
+ printk("direct_maping w/ start pfn %x, tot_pages %x.\n",
+ argbuf.start_pfn, argbuf.tot_pages);
+
+ addr = direct_mmap(argbuf.start_pfn << PAGE_SHIFT,
+ argbuf.tot_pages << PAGE_SHIFT,
+ PAGE_SHARED,
+ MAP_DISCONT,
+ argbuf.tot_pages);
+
+ printk("Picked vaddr %x.\n", addr);
+
+ return addr;
+}
+
+static int handle_dom0_cmd_unmapdommem(unsigned long data)
+{
+ struct dom0_unmapdommem_args argbuf;
+
+ if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
+ return -EFAULT;
+
+ return direct_disc_unmap(argbuf.vaddr, argbuf.start_pfn,
+ argbuf.tot_pages);
+}
+
static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long data)
{
switch (cmd) {
case IOCTL_DOM0_CREATEDOMAIN:
return handle_dom0_cmd_createdomain(data);
+ case IOCTL_DOM0_MAPDOMMEM:
+ return handle_dom0_cmd_mapdommem(data);
+ case IOCTL_DOM0_UNMAPDOMMEM:
+ return handle_dom0_cmd_unmapdommem(data);
default:
printk("Unknown dom0_cmd ioctl!\n");
return -EINVAL;